﻿using In66.Net.Core.System.Extensions.Expressions;
using In66.Net.Repository.IRepositories.ISqlSugar;

namespace Maint.Api.Services.Impl;

public class CfgAppService : AbstractAppService, ICfgAppService
{
    private readonly ISugarBaseRepository<Cfg> _cfgRepository;
    private readonly BloomFilterFactory _bloomFilterFactory;
    private readonly CacheService _cacheService;

    public CfgAppService(
        ISugarBaseRepository<Cfg> cfgRepository,
        BloomFilterFactory bloomFilterFactory,
        CacheService cacheService)
    {
        _cfgRepository = cfgRepository;
        _bloomFilterFactory = bloomFilterFactory;
        _cacheService = cacheService;
    }

    public async Task<AppSrvResult<long>> CreateAsync(CfgCreationDto input)
    {
        input.TrimStringFields();
        var exists = await _cfgRepository.ExistsAsync(x => x.Name.Equals(input.Name));
        if (exists)
        {
            return Problem(HttpStatusCode.BadRequest, "参数名称已经存在");
        }

        var cfg = Mapper.Map<Cfg>(input);
        cfg.Id = IdGenerater.GetNextId();

        var cacheKey = _cacheService.ConcatCacheKey(CachingConsts.CfgSingleKeyPrefix, cfg.Id);
        var cahceBf = _bloomFilterFactory.Create(CachingConsts.BloomfilterOfCacheKey);
        var addedStatus = await cahceBf.AddAsync(cacheKey);
        if (!addedStatus)
        {
            return Problem(HttpStatusCode.BadRequest, "添加到布隆过滤器失败!");
        }
        else
        {
            await _cfgRepository.InsertAsync(cfg);
        }

        return cfg.Id;
    }

    public async Task<AppSrvResult> UpdateAsync(long id, CfgUpdationDto input)
    {
        input.TrimStringFields();
        var exists = await _cfgRepository.ExistsAsync(c => c.Name.Equals(input.Name) && c.Id != id);
        if (exists)
        {
            return Problem(HttpStatusCode.BadRequest, "参数名称已经存在");
        }

        await _cfgRepository.Update(s => s.Id == id, f => new Cfg
        {
            Name = input.Name,
            Value = input.Value,
            Description = input.Description
        });

        return AppSrvResult();
    }

    public async Task<AppSrvResult> DeleteAsync(long id)
    {
        await _cfgRepository.DeleteByIdAsync(id);
        return AppSrvResult();
    }

    public async Task<CfgVo> GetAsync(long id)
    {
        var entity = await _cfgRepository.QueryByIdAsync(id);
        return Mapper.Map<CfgVo>(entity);
    }

    public async Task<PageModelVo<CfgVo>> GetPagedAsync(CfgSearchPagedDto search)
    {
        search.TrimStringFields();
        var whereExpression = ExpressionCreator
            .New<Cfg>()
            .AndIf(search.Name.IsNotNullOrWhiteSpace(), x => SqlFunc.Contains(x.Name, $"{search.Name}%"))
            .AndIf(search.Value.IsNotNullOrWhiteSpace(), x => SqlFunc.Contains(x.Value, $"{search.Value}%"));


        var total = await _cfgRepository.GetCountAsync(whereExpression);
        if (total == 0)
        {
            return new PageModelVo<CfgVo>(search);
        }

        var entities = _cfgRepository
                                        .QueryListByClause(whereExpression)
                                        .OrderByDescending(x => x.ModifyTime)
                                        .Skip(search.SkipRows())
                                        .Take(search.PageSize)
                                        .ToList();
        var cfgDtos = Mapper.Map<List<CfgVo>>(entities);

        return new PageModelVo<CfgVo>(search, cfgDtos, total);
    }
}